﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.RobotJog.CApRJRobotJogRotationCircleManager
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using EngineeringInternalExtension;
using System;
using Tecnomatix.Engineering;


namespace DnProcessSimulateCommands.RobotJog;

internal class CApRJRobotJogRotationCircleManager
{
  private const double MINIMAL_RADIUS = 0.0001;
  private TxManipulator _manipulator;

  public MovementAxis RotationAxis { get; private set; }

  public TxTransformation RotationCenter { get; private set; }

  public void ShowCircle(
    TxTransformation leadingObject,
    TxTransformation referenceFrame,
    TxTransformation delta)
  {
    MovementAxis movementAxis = CApRJRobotJogRotationCircleManager.GetMovementAxis(delta);
    this.ShowCircle(leadingObject, referenceFrame, movementAxis);
  }

  public void ShowCircle(
    TxTransformation leadingObject,
    TxTransformation referenceFrame,
    MovementAxis newRotationAxis)
  {
    if (newRotationAxis == this.RotationAxis && !TxManipulator.op_Equality(this._manipulator, (ITxObject) null))
      return;
    this.RotationAxis = newRotationAxis;
    if (CApRJRobotJogRotationCircleManager.IsMovementRotation(this.RotationAxis))
      this.UpdateCircle(leadingObject, referenceFrame);
    else
      this.HideCircle();
  }

  public void ShowCircle(TxTransformation leadingObject, TxTransformation referenceFrame)
  {
    this.UpdateCircle(leadingObject, referenceFrame);
  }

  public void HideCircle()
  {
    if (!TxManipulator.op_Inequality(this._manipulator, (ITxObject) null))
      return;
    this._manipulator.RemoveAllElements();
    TxObjectEx.ForceDeletion((ITxObject) this._manipulator);
    this._manipulator = (TxManipulator) null;
  }

  public static bool IsMovementRotation(MovementAxis movementAxis)
  {
    switch (movementAxis)
    {
      case MovementAxis.Rx:
      case MovementAxis.Ry:
      case MovementAxis.Rz:
        return true;
      default:
        return false;
    }
  }

  public static MovementAxis GetMovementAxis(TxTransformation delta)
  {
    TxVector translation = delta.Translation;
    if (Math.Abs(translation.X) > 0.0 || Math.Abs(translation.Y) > 0.0 || Math.Abs(translation.Z) > 0.0)
      return MovementAxis.T;
    TxVector rotationRpyXyz = delta.RotationRPY_XYZ;
    double num1 = Math.Abs(rotationRpyXyz.X);
    double num2 = Math.Abs(rotationRpyXyz.Y);
    double num3 = Math.Abs(rotationRpyXyz.Z);
    if (num1 > 0.0 && (num1 != Math.PI || num2 == 0.0 && num3 == 0.0))
      return MovementAxis.Rx;
    if (num2 > 0.0 && (num2 != Math.PI || num1 == 0.0 && num3 == 0.0))
      return MovementAxis.Ry;
    return num3 > 0.0 && (num3 != Math.PI || num1 == 0.0 && num2 == 0.0) ? MovementAxis.Rz : MovementAxis.None;
  }

  private void UpdateCircle(TxTransformation leadingObject, TxTransformation referenceFrame)
  {
    TxTransformation txTransformation1 = TxTransformation.op_Multiply(referenceFrame.Inverse, leadingObject);
    double distance;
    TxTransformation txTransformation2;
    switch (this.RotationAxis)
    {
      case MovementAxis.Rx:
        distance = CApRJRobotJogRotationCircleManager.GetDistance(txTransformation1.Translation.Y, txTransformation1.Translation.Z);
        TxVector txVector1 = TxVector.op_Multiply(new TxVector(1.0, 0.0, 0.0), txTransformation1.Translation.X);
        this.RotationCenter = TxTransformation.op_Multiply(referenceFrame, new TxTransformation(txVector1, (TxTransformation.TxTransformationType) 1));
        txTransformation2 = TxTransformation.op_Multiply(this.RotationCenter, new TxTransformation(new TxVector(0.0, Math.PI / 2.0, 0.0), (TxTransformation.TxRotationType) 1));
        break;
      case MovementAxis.Ry:
        distance = CApRJRobotJogRotationCircleManager.GetDistance(txTransformation1.Translation.X, txTransformation1.Translation.Z);
        TxVector txVector2 = TxVector.op_Multiply(new TxVector(0.0, 1.0, 0.0), txTransformation1.Translation.Y);
        this.RotationCenter = TxTransformation.op_Multiply(referenceFrame, new TxTransformation(txVector2, (TxTransformation.TxTransformationType) 1));
        txTransformation2 = TxTransformation.op_Multiply(this.RotationCenter, new TxTransformation(new TxVector(Math.PI / 2.0, 0.0, 0.0), (TxTransformation.TxRotationType) 1));
        break;
      case MovementAxis.Rz:
        distance = CApRJRobotJogRotationCircleManager.GetDistance(txTransformation1.Translation.X, txTransformation1.Translation.Y);
        TxVector txVector3 = TxVector.op_Multiply(new TxVector(0.0, 0.0, 1.0), txTransformation1.Translation.Z);
        this.RotationCenter = TxTransformation.op_Multiply(referenceFrame, new TxTransformation(txVector3, (TxTransformation.TxTransformationType) 1));
        txTransformation2 = new TxTransformation(this.RotationCenter);
        break;
    }
  }

  private static double GetDistance(double x, double y) => Math.Sqrt(x * x + y * y);

  private void CreateManipulator(TxTransformation position, double radius)
  {
    if (TxManipulator.op_Inequality(this._manipulator, (ITxObject) null))
      this.HideCircle();
    if (radius < 0.0001)
      return;
    TxManipulatorCreationData manipulatorCreationData = new TxManipulatorCreationData();
    ((TxLocatableObjectCreationData) manipulatorCreationData).AbsoluteLocation = position;
    this._manipulator = TxApplication.ActiveDocument.PhysicalRoot.CreateManipulator(manipulatorCreationData);
    this.CreateCircle(radius);
  }

  private void CreateCircle(double radius)
  {
    TxManipulatorArcElementData manipulatorArcElementData = new TxManipulatorArcElementData(new TxTransformation(), radius, radius, 0.0, 2.0 * Math.PI, 30);
    ((TxManipulatorElementData) manipulatorArcElementData).Pickable = false;
    ((TxManipulatorElementData) manipulatorArcElementData).Color = TxColor.TxColorWhite;
    ((TxManipulatorElementData) manipulatorArcElementData).AntiAlias = true;
    ((TxManipulatorElementData) manipulatorArcElementData).Unzoomable = false;
    ((TxManipulatorElementData) manipulatorArcElementData).Visibility = (TxManipulatorElementData.TxManipulatorElementVisibility) 65280;
    this._manipulator.AddElement((TxManipulatorElementData) manipulatorArcElementData);
    this._manipulator.Display();
  }
}
